package com.example.leave.service.impl;

import com.example.leave.common.*;
import com.example.leave.component.equator.Equator;
import com.example.leave.component.equator.FieldInfo;
import com.example.leave.component.equator.GetterBaseEquator;
import com.example.leave.dao.LeaveFromOperationHistoryRepository;
import com.example.leave.dto.ChangeHistory;
import com.example.leave.dto.LeaveFormOperationHistoryDto;
import com.example.leave.entity.LeaveForm;
import com.example.leave.entity.LeaveFormOperationHistory;
import com.example.leave.enums.OperationEnum;
import com.example.leave.exception.BizException;
import com.example.leave.form.IdAndPageInfoForm;
import com.example.leave.form.IdAndTimeBetweenAndPageInfoVoForm;
import com.example.leave.service.LeaveFormOperationHistoryService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

@Service
public class LeaveFormLeaveFormOperationHistoryImpl implements LeaveFormOperationHistoryService {

    @Autowired
    LeaveFromOperationHistoryRepository leaveFromOperationHistoryRepository;

    @Override
    public void addOperation(LeaveForm newLeaveForm) {
        try {
            LeaveFormOperationHistory leaveFormOperationHistory = getCommonOperation(newLeaveForm);
            leaveFormOperationHistory.setAction(OperationEnum.ADD.getCode());
            leaveFromOperationHistoryRepository.save(leaveFormOperationHistory);
        } catch (Exception e) {
            throw new BizException("操作记录保存失败");
        }

    }

    @Override
    public void deleteOperation(String leaveFormId) {
        try {
            LeaveFormOperationHistory leaveFormOperationHistory = getCommonOperation(leaveFormId);
            leaveFormOperationHistory.setAction(OperationEnum.DELETE.getCode());
            leaveFromOperationHistoryRepository.save(leaveFormOperationHistory);
        } catch (Exception e) {
            throw new BizException("操作记录保存失败");
        }

    }

    @Override
    public void updateOperation(LeaveForm newLeaveForm) {
        try {
            LeaveFormOperationHistory leaveFormOperationHistory = getCommonOperation(newLeaveForm);
            leaveFormOperationHistory.setAction(OperationEnum.UPDATE.getCode());
            leaveFromOperationHistoryRepository.save(leaveFormOperationHistory);
        } catch (Exception e) {
            throw new BizException("操作记录保存失败");
        }

    }

    @Override
    public CommonPage<LeaveFormOperationHistoryDto> findByUserId(IdAndPageInfoForm userIdAndPageInfoForm) {
        Page<LeaveFormOperationHistory> leaveFormOperationHistoryDtoList =
                leaveFromOperationHistoryRepository.findByUserId(userIdAndPageInfoForm.getId(),
                        PageUtil.pageInfoToPageable(userIdAndPageInfoForm.getPageInfoForm()));
        return CommonPage.getCommonPage(leaveFormOperationHistoryDtoList, userIdAndPageInfoForm.getPageInfoForm().getSort());
    }

    @Override
    public CommonPage<LeaveFormOperationHistoryDto> findByOperatorAndOperationTimeBetween
            (IdAndTimeBetweenAndPageInfoVoForm operatorAndTimeBetweenAndPageInfoVo) {
        Page<LeaveFormOperationHistory> leaveFormOperationHistoryPage =
                leaveFromOperationHistoryRepository.findByOperatorAndOperationTimeBetween(
                        operatorAndTimeBetweenAndPageInfoVo.getId(),
                        DateTimeUtil.dateTimeToTimestamp(operatorAndTimeBetweenAndPageInfoVo.getStart()),
                        DateTimeUtil.dateTimeToTimestamp(operatorAndTimeBetweenAndPageInfoVo.getEnd()),
                        PageUtil.pageInfoToPageable(operatorAndTimeBetweenAndPageInfoVo.getPageInfoForm()));
        return CommonPage.getCommonPage(leaveFormOperationHistoryPage, operatorAndTimeBetweenAndPageInfoVo.getPageInfoForm().getSort());

    }

    @Override
    public CommonPage<LeaveFormOperationHistoryDto> findByLeaveFormId(IdAndPageInfoForm leaveFormIdAndPageInfoForm) {
        Page<LeaveFormOperationHistory> leaveFormOperationHistoryDtoPage =
                leaveFromOperationHistoryRepository.findByLeaveFormId(leaveFormIdAndPageInfoForm.getId(),
                        PageUtil.pageInfoToPageable(leaveFormIdAndPageInfoForm.getPageInfoForm()));
        return CommonPage.getCommonPage(leaveFormOperationHistoryDtoPage, leaveFormIdAndPageInfoForm.getPageInfoForm().getSort());
    }

    @Override
    public List<ChangeHistory> findChangeByLeaveFormId(IdAndPageInfoForm leaveFormIdAndPageInfoForm) {
        Page<LeaveFormOperationHistory> leaveFormOperationHistoryPage = leaveFromOperationHistoryRepository
                .findByLeaveFormIdOrderByOperationTime(leaveFormIdAndPageInfoForm.getId(),
                        PageUtil.pageInfoToPageable(leaveFormIdAndPageInfoForm.getPageInfoForm()));

        List<LeaveFormOperationHistory> leaveFormOperationHistories = leaveFormOperationHistoryPage.getContent();
        if (leaveFormOperationHistories.isEmpty()) {
            throw new BizException("未查到任何记录");
        }
        List<ChangeHistory> changeHistoryList = new ArrayList<>();

        for (int i = 0; i < leaveFormOperationHistories.size(); i++) {
            LeaveFormOperationHistory leaveFormOperationHistory = leaveFormOperationHistories.get(i);
            Equator equator = new GetterBaseEquator();
            if (i == 0) {
                ChangeHistory changeHistory = new ChangeHistory();
                changeHistory.setAction(OperationEnum.ADD.getOperation());
                changeHistory.setOperationTime(leaveFormOperationHistory.getOperationTime());
                changeHistory.setOperator(leaveFormOperationHistory.getOperator());
                List<FieldInfo> diff = equator.getDiffFields(
                        new LeaveFormOperationHistory(), leaveFormOperationHistory);
                changeHistory.setUpdateInfoList(diff);
                changeHistoryList.add(changeHistory);
            } else if (leaveFormOperationHistory.getAction() == OperationEnum.UPDATE.getCode()) {
                ChangeHistory changeHistory = new ChangeHistory();
                changeHistory.setAction(OperationEnum.UPDATE.getOperation());
                changeHistory.setOperationTime(leaveFormOperationHistory.getOperationTime());
                changeHistory.setOperator(leaveFormOperationHistory.getOperator());
                List<FieldInfo> diff = equator.getDiffFields(
                        leaveFormOperationHistories.get(i - 1), leaveFormOperationHistory);
                changeHistory.setUpdateInfoList(diff);
                changeHistoryList.add(changeHistory);
            } else if (leaveFormOperationHistory.getAction() == OperationEnum.DELETE.getCode()) {
                ChangeHistory changeHistory = new ChangeHistory();
                changeHistory.setAction(OperationEnum.DELETE.getOperation());
                changeHistory.setOperationTime(leaveFormOperationHistory.getOperationTime());
                changeHistory.setOperator(leaveFormOperationHistory.getOperator());
                List<FieldInfo> diff = equator.getDiffFields(
                        leaveFormOperationHistory, new LeaveFormOperationHistory());
                changeHistory.setUpdateInfoList(diff);
                changeHistoryList.add(changeHistory);
            }
        }
        return changeHistoryList;
    }

    private LeaveFormOperationHistory getCommonOperation(String leaveFormId) {

        LeaveFormOperationHistory leaveFormOperationHistory = new LeaveFormOperationHistory();
        leaveFormOperationHistory.setLeaveFormId(leaveFormId);
        leaveFormOperationHistory.setId(UuidUtil.getUuid32());
        leaveFormOperationHistory.setOperationTime(new Timestamp(System.currentTimeMillis()));
        leaveFormOperationHistory.setOperator(JwtUtil.getUserFromToken().getId());
        return leaveFormOperationHistory;
    }

    private LeaveFormOperationHistory getCommonOperation(LeaveForm leaveForm) {
        LeaveFormOperationHistory leaveFormOperationHistory = new LeaveFormOperationHistory();
        BeanUtils.copyProperties(leaveForm, leaveFormOperationHistory);
        leaveFormOperationHistory.setLeaveFormId(leaveForm.getId());
        leaveFormOperationHistory.setId(UuidUtil.getUuid32());
        leaveFormOperationHistory.setOperationTime(new Timestamp(System.currentTimeMillis()));
        leaveFormOperationHistory.setOperator(JwtUtil.getUserFromToken().getId());
        return leaveFormOperationHistory;
    }
}
